package com.xpec.c4.codec.h2o;


public class H2oInputStream {
	
	protected static byte readNoVarintByte(H2oBuffer buffer) throws Exception {
		return buffer.get();
	}

//	public static int readTag(ByteBuffer buffer) throws Exception {
//
//		int lastTag = (int) readRawVarint(buffer);
//
//		// if (MyWireFormat.getTagFieldNumber(lastTag) == 0) {
//		// throw new Exception("invalid tag");
//		// }
//
//		return lastTag;
//	}

//	public static int readRawVarint32(ByteBuffer buffer) throws Exception {
//		byte tmp = buffer.get();
//		if (tmp >= 0) {
//			return tmp;
//		}
//		int result = tmp & 0x7f;
//		if ((tmp = buffer.get()) >= 0) {
//			result |= tmp << 7;
//		} else {
//			result |= (tmp & 0x7f) << 7;
//			if ((tmp = buffer.get()) >= 0) {
//				result |= tmp << 14;
//			} else {
//				result |= (tmp & 0x7f) << 14;
//				if ((tmp = buffer.get()) >= 0) {
//					result |= tmp << 21;
//				} else {
//					result |= (tmp & 0x7f) << 21;
//					result |= (tmp = buffer.get()) << 28;
//					if (tmp < 0) {
//						// Discard upper 32 bits.
//						for (int i = 0; i < 5; i++) {
//							if (buffer.get() >= 0) {
//								return result;
//							}
//						}
//						throw new Exception("malformed varint 32");
//					}
//				}
//			}
//		}
//		return result;
//	}

	protected static long readRawVarint(H2oBuffer buffer) throws Exception {
		int shift = 0;
		long result = 0;
		while (shift < 64) {
			final byte b = buffer.get();
			result |= (long) (b & 0x7F) << shift;
			if ((b & 0x80) == 0) {
				return result;
			}
			shift += 7;
		}
		throw new Exception("malformed varint 64");
	}

	protected static boolean readBoolean(H2oBuffer buffer) throws Exception {
		return readByte(buffer) == 1;
	}

	protected static byte readByte(H2oBuffer buffer) throws Exception {
		return buffer.get();
	}

	protected static char readChar(H2oBuffer buffer) throws Exception {
		long value = readRawVarint(buffer);
		if (value > Character.MAX_VALUE || value < Character.MIN_VALUE) {
			throw new Exception("bad char format!");
		}
		return (char) value;
	}

	protected static short readShort(H2oBuffer buffer) throws Exception {
		long value = readRawVarint(buffer);
		if (value > Short.MAX_VALUE || value < Short.MIN_VALUE) {
			throw new Exception("bad short format!");
		}
		return (short) value;
	}

	protected static byte[] readBytes(H2oBuffer buffer) throws Exception {
		int size = (int) readRawVarint(buffer);
		byte[] bytes = new byte[size];
		buffer.get(bytes);
		return bytes;
	}

	protected static String readString(H2oBuffer buffer) throws Exception {
		byte[] bytes = readBytes(buffer);

		if (bytes == null) {
			return null;
		}

		return new String(bytes, CodedInfo.CHARSET_NAME);
	}
	
	protected static float readFloat(H2oBuffer buffer) throws Exception {
		return buffer.getFloat();
	}
	
	protected static double readDouble(H2oBuffer buffer) throws Exception {
		return buffer.getDouble();
	}
}
